/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain (a) copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.kizitonwose.calendarview.model;

import java.io.Serializable;
import java.time.YearMonth;
import java.util.List;

/**
 * CalendarMonth
 *
 * @since 2021-02-26
 */
public class CalendarMonth implements Comparable, Serializable {
    private final int indexInSameMonth;
    private final int numberOfSameMonth;
    private final int year;
    private final int month;

    private final YearMonth yearMonth;
    private final List<List<CalendarDay>> weekDays;

    /**
     * CalendarMonth
     *
     * @param yearMonth YearMonth
     * @param weekDays List
     * @param indexInSameMonth int
     * @param numberOfSameMonth int
     */
    public CalendarMonth(YearMonth yearMonth, List weekDays, int indexInSameMonth, int numberOfSameMonth) {
        this.yearMonth = yearMonth;
        this.weekDays = weekDays;
        this.indexInSameMonth = indexInSameMonth;
        this.numberOfSameMonth = numberOfSameMonth;
        this.year = this.yearMonth.getYear();
        this.month = this.yearMonth.getMonthValue();
    }

    public int getYear() {
        return year;
    }

    public int getMonth() {
        return month;
    }

    @Override
    public int hashCode() {
        return 31 * this.yearMonth.hashCode() + getFirst(weekDays).hashCode()
            + getLast(weekDays).hashCode();
    }

    @Override
    public boolean equals(Object other) {
        if (this == other) {
            return true;
        } else if (!(other instanceof CalendarMonth)) {
            return false;
        } else {
            CalendarMonth mCalendarMonth = (CalendarMonth) other;
            return yearMonth.equals(mCalendarMonth.yearMonth)
                && getFirst(weekDays).equals(getFirst(mCalendarMonth.weekDays))
                && getLast(weekDays).equals(getLast(mCalendarMonth.weekDays));
        }
    }

    /**
     * getLast
     *
     * @param weekDays List
     * @return CalendarDay
     */
    public static CalendarDay getLast(List<List<CalendarDay>> weekDays) {
        if (weekDays == null) {
            return null;
        }
        List<CalendarDay> mList = weekDays.get(weekDays.size() - 1);
        return mList.get(mList.size() - 1);
    }

    private CalendarDay getFirst(List<List<CalendarDay>> weekDays) {
        if (weekDays == null) {
            return null;
        }
        return weekDays.get(0).get(0);
    }

    /**
     * compareTo
     *
     * @param calendarMonth CalendarMonth
     * @return monthResult int
     */
    public int compareTo(CalendarMonth calendarMonth) {
        int monthResult = this.yearMonth.compareTo(calendarMonth.yearMonth);
        return monthResult == 0 ? Integer.compare(indexInSameMonth, calendarMonth.indexInSameMonth) : monthResult;
    }

    @Override
    public int compareTo(Object object) {
        return this.compareTo((CalendarMonth) object);
    }

    @Override
    public String toString() {
        return "CalendarMonth { first = " + getFirst(weekDays) + ", last = " + getLast(weekDays)
            + "} " + "indexInSameMonth = " + this.indexInSameMonth + ", numberOfSameMonth = " + this.numberOfSameMonth;
    }

    public final YearMonth getYearMonth() {
        return this.yearMonth;
    }

    public final List getWeekDays() {
        return this.weekDays;
    }

    public int getIndexInSameMonth() {
        return indexInSameMonth;
    }

    public int getNumberOfSameMonth() {
        return numberOfSameMonth;
    }
}
